"""
Auth: Mushroom Whistler(zhangyufei49@163.com)
Date: 2016-05-24
Desc: convert std python value to lua table value
"""

def convert(pydata):
    """
    convert python iteratiable value to lua table string.
    pydata: a python iteratiable value
    returns: None for failed. lua table utf-8 string for successed.
    """
    def indentstr(indentlevel):
        return indentlevel * 4 * " "

    def tidxstr(idx):
        it = type(idx)
        if it == int:
            return '[%d] = ' % idx
        elif it == str:
            return '["%s"] = ' % idx
        elif it == unicode:
            return '["%s"] = ' % idx.encode('utf-8')
        elif it == float:
            return '[%f] = ' % idx
        else:
            print "unsupported lua table index type: %s" % it
            exit(1)

    def isiteratiable(v):
        t = type(v)
        ok = (t == dict) or (t == tuple) or (t == list)
        return ok, t

    def tobaseval(d, t):
        def tostr(d):
            # start with '#' mean upvalue
            if d[0] == '#':
                return '%s,' % d[1:]
            else:
                return '"%s",' % d

        if d is None:
            return 'nil,'
        if t == int:
            return '%d,' % d
        if t == str:
            return tostr(d)
        if t == unicode:
            return tostr(d.encode('utf-8'))
        if t == float:
            return '%f,' % d
        if t == bool:
            return '%s,' % (d and "true" or "false")

    def totable(idx, val, out, indentlevel = 0):
        idxstr = ""
        if idx:
            idxstr = "%s%s" % (indentstr(indentlevel), tidxstr(idx))
        ok, t = isiteratiable(val)
        if ok:
            preindentl = indentlevel
            indentlevel = indentlevel + 1
            out.append(idxstr + "{")

            if t == dict:
                for k in val:
                    totable(k, val[k], out, indentlevel)
            else:
                i = 1
                for d in val:
                    totable(i, d, out, indentlevel)
                    i = i + 1

            nb = indentstr(preindentl)
            out.append((idx != None) and ("%s}," % nb) or ("%s}" % nb))
        else:
            out.append(idxstr + tobaseval(val, t))

    # check the param pydata
    ok, t = isiteratiable(pydata)
    if not ok:
        return None

    # do convert
    ret = []
    totable(None, pydata, ret)
    return "\n".join(ret)
